#include <rtc_base/logging.h>

#include "transport_controller.h"

namespace xrtc {

TransportController::TransportController(EventLoop *el, PortAllocator *allocator)  
                                        : m_el(el), m_ice_agent(new IceAgent(el, allocator)) 
{
    m_ice_agent->signal_candidate_allocate_done.connect(this, &TransportController::on_candidate_allocate_done);
}                                        


// 设置本地描述，创建通道，收集candidate    
int TransportController::set_local_description(SessionDescription* desc) {
    if (!desc) {
        RTC_LOG(LS_ERROR) << "description is null.";
        return -1;
    }

    for (auto content : desc->getContents()) {
        // 获取mid（音频通道还是视频通道）
        std::string mid = content->mid();
        // 此处条件下不创建传输通道，传输通道复用
        if (desc->is_bundle(mid) && mid != desc->get_first_bundle_mid()) {
            continue;
        }

        // 创建RTP传输通道
        m_ice_agent->create_channel(m_el, mid, IceCandidateComponent::RTP);
        auto td = desc->getTransportInfo(mid);
        if (td) {
            m_ice_agent->set_ice_parameters(mid, IceCandidateComponent::RTP, 
                IceParameters(td->m_ICE_ufrag, td->m_ICE_pwd));
        }
    }

    m_ice_agent->gathering_candidate();

    return 0;
}

int TransportController::set_remote_description(SessionDescription *desc)
{
    if (!desc) { 
        return -1;
    }

    for (auto content : desc->getContents()) {
        std::string mid = content->mid();
        if (desc->is_bundle(mid) && mid != desc->get_first_bundle_mid()) {
            continue;
        }

        auto td = desc->getTransportInfo(mid);
        if (td) {
            // 设置ICE参数
            m_ice_agent->set_remote_ice_params(mid, IceCandidateComponent::RTP, 
            IceParameters(td->m_ICE_ufrag, td->m_ICE_pwd)); 
        }
    }
    
    return 0;
}

void TransportController::on_candidate_allocate_done(IceAgent * /* agent */ , const std::string &transport_name, IceCandidateComponent component, const std::vector<Candidate> &candidates)
{
    // 继续抛给上层（PeerConnection）
    signal_candidate_allocate_done(this, transport_name, component, candidates);
}

}
